package com.ymttest.utils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;


/************************************************************************************
 * 用于处理日志
 * 
 * @File name : Logger.java
 * @Author : zhouyi
 * @Date : 2015年3月11日
 * @Copyright : 洋码头
 ************************************************************************************/
@SuppressWarnings("deprecation")
public class Logger2Debug{

    private static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();

    private static boolean debug = true;
    private static boolean outFile = false;
    private static String logFile="debug.log";
    private static void buildResultFlag(Boolean flag) {
//        Map<String, Object> map = threadLocal.get();
//        map.put("resultFlag", flag);
    }

    private static Boolean getResultFlag() {
        Map<String, Object> map = threadLocal.get();
        if (map == null)
            return null;
        return (Boolean) map.get("resultFlag");
    }
    
    private static void buildErrorMessage(StringBuffer message) {
        Map<String, Object> map = threadLocal.get();
        map.put("errorMessage", message);
    }

    private static StringBuffer getErrorMessage() {
        Map<String, Object> map = threadLocal.get();
        if (map == null) {
			threadLocal.set(new HashMap<>());
			threadLocal.get().put("errorMessage", new StringBuffer());
			return (StringBuffer) threadLocal.get().get("errorMessage");
		}
        return (StringBuffer) map.get("errorMessage");
    }
    
    private static void buildTestsuiteDesc(String desc) {
        Map<String, Object> map = threadLocal.get();
        map.put("testsuiteDesc", desc);
    }

    private static String getTestsuiteDesc() {
        Map<String, Object> map = threadLocal.get();
        if (map == null)
            return null;
        return (String) map.get("testsuiteDesc");
    }
    /**
     * 最后把日志写入文件，关闭流<br>
     * 建议在AfterClass调用
     */
    public static void generateResult(String apiName) {
    }

    /**
     * 最后把日志写入文件，关闭流<br>
     * 建议在AfterClass调用
     */
    @Deprecated
    public static void generateResult() {}

    /**
     * 以每个用例单独生成xml报表后，该方法废弃
     * 创建日志文件<br>
     * 建议在BeforeClass时调用
     * 
     * @param description 该日志对应描述，此参数暂时没有作用
     */
    public static void createResultFile(String description) {
    	
        threadLocal.set(new HashMap<String, Object>());
    	buildTestsuiteDesc(description);
    }

    /**
     * 添加一个comment
     * 
     * @param message comment信息
     */
    public static void comment(String message) {
        debug(message);
    }

    /**
     * 打印到控制台 --debug为true时输出 System.err.println
     * 
     * @param message
     */
    public static void debug(Object message) {
    	
        if (debug) {
            String name = Thread.currentThread().getName();
            System.out.println("Thread:" + name + " " + getNow() + " " + message.toString());
            if(outFile){
            	TestDataManager.appendFileToLine(logFile, "Thread:" + name + " " + getNow() + " " + message.toString());
            }
        }
    }
    
    /**
     * 打印到控制台 --debug为true时输出 System.err.println
     * 
     * @param message
     */
    public static void info(Object message) {
    	
            String name = Thread.currentThread().getName();
            System.out.println("Thread:" + name + " " + getNow() + " " + message.toString());
    }

    /**
     * 开始记录Testcase，在case开始时调用
     * 
     * @param type 正反例 正例true
     * @param description Testcase描述
     */
    public static void start(boolean type, String description) {

        //flag = true;
        buildResultFlag(true);
        StringBuffer message=new StringBuffer();
        buildErrorMessage(message);
        
        debug(getTestsuiteName() + " " + getTestName());
        debug(description);

        String testname = getTestName();
        debug("开始执行测试用例:" + testname);
    }

    /**
     * 开始记录Testcase，在case开始时调用
     * 
     * @param description Testcase描述
     * @deprecated
     */
    public static void start(String description) {
        //flag = true;
        buildResultFlag(true);
        StringBuffer message=new StringBuffer();
        buildErrorMessage(message);
        String testname = getTestName();
        debug("开始执行测试用例:" + testname);
    }

    /**
     * 结束case，在After调用
     */
    public static void end() {
    	boolean flag=getResultFlag()==null?true:getResultFlag();
	    if (!flag) {
	        	String message=getErrorMessage().toString();
	        	
	            org.junit.Assert.fail(message==null?"null":message);
	       }
    	 
    }

    /**
     * 描述case失败
     * 
     * @param exception 失败异常
     */
    public static void fail(Exception exception) {
        exception.printStackTrace();
        StackTraceElement exmsg = exception.getStackTrace()[0];
        getErrorMessage().append(new SimpleDateFormat("yyyyMMddhhmmssSSS").format(Calendar.getInstance().getTime()) + ":" + "\r\n");
        getErrorMessage().append("错误:" + exmsg.toString() + ":" + "\r\n");
        getErrorMessage().append("+++++错误信息:" + exception.getMessage() + ":" + "\r\n");
        debug("Error:" + exmsg.toString() + "+++++ExceptionMsg:" + exception.getMessage());
        org.junit.Assert.fail();
    }

    /**
     * 描述case设置阶段日志
     * 
     * @param msg setup信息
     * @param pass setup是否成功 0成功 其他失败
     */
    public static void setup(String msg, int pass) {
        if (pass == 0) {
            debug(msg + ":pass");
        } else {
            debug(msg + ":failed");
        }
    }

    /**
     * 描述case Cleanup阶段日志
     * 
     * @param msg Cleanup信息
     * @param pass Cleanup是否成功 0成功 其他失败
     */
    public static void cleanup(String msg, int pass) {
        if (pass == 0) {
            debug(msg + ":pass");
        } else {
            debug(msg + ":failed");
        }
    }

    /**
     * 断言期望和实际相等
     * 
     * @param expected 期望
     * @param actual 实际
     * @param Description 断言描述
     */
    public static boolean verifyEquals(Object expected, Object actual, String Description) {
    	boolean vflag=true;
        if (expected == null || actual == null) {
            if (expected == actual) {
            } else {
                buildResultFlag(false);
                vflag=false;
                getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
                getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
                getErrorMessage().append("\n" + Description + "\t期望：" + expected + " 实际：" + actual);
            }
        } else if (expected.equals(actual)) {
        	debug("Success:"+Description + "\t期望：" + expected + " 实际：" + actual);
        } else {
            buildResultFlag(false);
            vflag=false;
            
            getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
            getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
            getErrorMessage().append("\n" + Description + "\t期望：" + expected.toString() + " 实际：" + actual.toString());
            debug(getErrorMessage().toString());
        }
        
        return vflag;
    }

    /**
     * 断言期望和实际不相等
     * 
     * @param expected 期望
     * @param actual 实际
     * @param Description 断言描述
     */
    public static boolean verifyNotEquals(Object expected, Object actual, String Description) {
    	boolean vflag=true;
        if (!expected.equals(actual)) {
            if (actual == null)
                actual = "";
        } else {
            buildResultFlag(false);
            vflag=false;
            getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
            getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
            getErrorMessage().append("\n" + "期望：" + expected.toString() + " 不等于 实际：" + actual.toString());
            debug(getErrorMessage().toString());
        }
        return vflag;
    }

    /**
     * 断言期望对象非空
     * 
     * @param obj 期望对象
     * @param Description 断言描述
     */
    public static boolean verifyNotNull(Object obj, String Description) {
    	boolean vflag=true;
        if (obj != "null" && obj != null && obj.toString().length() != 0) {
        } else {
            buildResultFlag(false);
            vflag=false;
            getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
            getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
            getErrorMessage().append("\n" + "Expected：NotNull  Actual：Null");
            getErrorMessage().append("	" + Description);

            debug(getErrorMessage().toString());
        }
        return vflag;
    }

    /**
     * 断言期望对象为空
     * 
     * @param obj 期望对象
     * @param Description 断言描述
     */
    public static boolean verifyIsNull(Object obj, String Description) {
    	boolean vflag=true;
        if (obj == null || obj == "null" || obj.toString().length() == 0) {
        } else {
            buildResultFlag(false);
            vflag=false;
            getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
            getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
            getErrorMessage().append("\n" + "期望：Null  实际：" + obj.toString());
            getErrorMessage().append("	" + Description);
            debug(getErrorMessage().toString());
        }
        return vflag;
    }

    /**
     * 断言实际内容中包含期望信息
     * 
     * @param expected 期望
     * @param actual 实际
     * @param Description 断言描述
     */
    public static boolean verifyIsContains(Object expected, Object actual, String Description) {
    	boolean vflag=true;
        if (expected == null || actual == null) {
            if (expected.toString().contains(actual.toString()) && expected.toString().length() > 0
                    && actual.toString().length() > 0) {
            } else {
                buildResultFlag(false);
                vflag=false;
                
                getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
                getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
                getErrorMessage().append("\n" + Description + "\t期望：" + expected + " 实际：" + actual);

            }
        } else if (actual.toString().contains(expected.toString())) {
        } else {
            buildResultFlag(false);
            vflag=false;
            
            getErrorMessage().append("\nClassName:" + Thread.currentThread().getStackTrace()[2].getClassName());
            getErrorMessage().append("\nLine:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
            getErrorMessage().append("\n" + Description + "\t期望：" + expected.toString() + " 实际：" + actual.toString());
            debug(getErrorMessage().toString());

        }
        return vflag;
    }

    /**
     * 获取 getTestName
     * 
     * @return 调用日志的测试方法的MethodName
     */
    private static String getTestName() {
        return Thread.currentThread().getStackTrace()[3].getMethodName();
    }

    /**
     * 获取 getLineNum
     * 
     * @return 调用日志的测试方法的getLineNumber
     */
    private static int getLineNum() {
        return Thread.currentThread().getStackTrace()[3].getLineNumber();
    }

    /**
     * 获取 getTestsuiteName
     * 
     * @return 调用日志的测试类的ClassName
     */
    private static String getTestsuiteName() {
        return Thread.currentThread().getStackTrace()[3].getClassName();
    }

    /**
     * 获取当前日志是否为debug模式
     * 
     * @return
     */
    public static boolean isDebug() {
        return debug;
    }

    /**
     * 设置当前日志是否为debug模式
     * 
     * @param debug
     */
    public static void setDebug(boolean debug) {
        Logger2Debug.debug = debug;
    }

    /**
     * 获取当前时间
     * 
     * @return {yyyy-MM-dd HH:mm:ss.SSS}
     */
    private static String getNow() {
        Calendar calendar = Calendar.getInstance();
        String strSysTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(calendar.getTime());
        return strSysTime;
    }
}
